package com.tmindtech.api.foodsafe.service

import com.tmindtech.api.dept.db.DeptMapper
import com.tmindtech.api.dept.model.Department
import com.tmindtech.api.enterprise.db.EnterpriseMapper
import com.tmindtech.api.enterprise.model.Enterprise
import com.tmindtech.api.foodsafe.db.GpsDataMapper
import com.tmindtech.api.foodsafe.db.PhoneGpsMapMapper
import com.tmindtech.api.foodsafe.model.GpsData
import com.tmindtech.api.foodsafe.model.PhoneGpsMap
import com.tmindtech.api.justice.db.JusticeStaffMapper
import com.tmindtech.api.justice.model.JusticeStaff
import com.tmindtech.api.justice.model.StaffType
import com.tmindtech.api.utils.importCsv
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import org.springframework.transaction.annotation.Transactional
import java.io.InputStream
import java.text.SimpleDateFormat

/**
 * Created by RexQian on 2017/11/27.
 */
@Component
class FoodSafeCsvImport {
    @Autowired
    lateinit var deptMapper: DeptMapper

    @Autowired
    lateinit var staffMapper: JusticeStaffMapper

    @Autowired
    lateinit var phoneGpsMapMapper: PhoneGpsMapMapper

    @Autowired
    lateinit var enterpriseMapper: EnterpriseMapper

    @Transactional
    fun importDeptCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2Dept(line) ?: return@importCsv false
            val existItem = deptMapper.selectOne(Department(outId = item.outId))
            if (existItem != null) {
                item.id = existItem.id
                deptMapper.updateByPrimaryKeySelective(item)
            } else {
                deptMapper.insertSelective(item)
            }
            return@importCsv true
        }
    }

    private fun line2Dept(line: Array<String>): Department? {
        val item = Department()
        item.name = line[2].trim()
        val parentItem = deptMapper.selectOne(Department(outId = line[3].trim()))
        item.parentId = parentItem?.id ?: 0
        item.level = parentItem?.level?.plus(1) ?: 0
        item.isInstance = true
        item.isFixedId = false
        item.outId = line[0].trim()
        item.longitude = line[11].trim().toDoubleOrNull()
        item.latitude = line[12].trim().toDoubleOrNull()
        item.address = line[13].trim()
        return item
    }

    @Transactional
    fun importStaffCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2Staff(line) ?: return@importCsv false
            staffMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2Staff(line: Array<String>): JusticeStaff? {
        val dept = deptMapper.selectOne(Department(name = line[0].trim())) ?: return null
        val item = JusticeStaff()
        item.name = line[1].trim()
        item.phone = line[3].trim()
        item.deptId = dept.id
        item.type = StaffType.FoodSafe.value
        return item
    }

    @Transactional
    fun importGpsMapCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2GpsMap(line)
            phoneGpsMapMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2GpsMap(line: Array<String>): PhoneGpsMap? {
        val phoneGpsMap = PhoneGpsMap()
        phoneGpsMap.phone = line[3].trim()
        phoneGpsMap.gpsId = line[0].trim()
        return phoneGpsMap
    }

    @Autowired
    lateinit var gpsDataMapper: GpsDataMapper

    @Transactional
    fun importGpsDataCsv(inputStream: InputStream) {
        importCsv(inputStream) { line ->
            val item = line2GpsData(line) ?: return@importCsv false
            gpsDataMapper.insertSelective(item)
            return@importCsv true
        }
    }

    private fun line2GpsData(line: Array<String>): GpsData? {
        val item = GpsData()
        item.enterpriseId = enterpriseMapper.selectOne(Enterprise(regCode = line[4].trim()))?.id ?: return null
        item.gpsId = line[1].trim()
        item.longitude = line[9].trim().toDoubleOrNull() ?: return null
        item.latitude = line[10].trim().toDoubleOrNull() ?: return null
        val dateFormat = SimpleDateFormat("yyyy/MM/dd HH:mm")
        item.uploadDate = dateFormat.parse(line[3].trim())
        return item
    }
}